import { Component, OnInit, Input, ViewChild } from '@angular/core';
import { SwaggerService } from '../../services';
import { IDefinitionProperty } from '../../interfaces';
import { SwaggerTools } from '../../tools';

@Component({
  selector: 'swagger-ref-item',
  templateUrl: './swagger-ref-item.component.html',
  styles: []
})
export class SwaggerRefItemComponent implements OnInit {
  @Input()
  set ref(value: string) {
    this.data = this.swaggerService.getRef(value);
  }

  @ViewChild('editor') editor: any;

  editorOptions = {
    // theme: 'vs-dark',
    language: 'json',
    folding: true
  };
  code: any;

  _data: IDefinitionProperty[];
  @Input() set data(value) {
    this._data = value;
    this._data.forEach(item => {
      this.expandDataCache[item.key] = this.covert(item);
      this.code = JSON.stringify(this.expandDataCache);
    });
  }
  expandDataCache = {};

  constructor(
    private swaggerService: SwaggerService
  ) { }

  ngOnInit() {
  }

  hasExpand(row) {
    return SwaggerTools.hasRefByDefinitionProperty(row);
  }

  covert(root: any) {
    const stack = [], array = [], hashMap = {};
    stack.push({ ...root, level: 0, expand: false });

    while (stack.length != 0) {
      const node = stack.pop();
      this.visitNode(node, hashMap, array);
      if (SwaggerTools.hasRefByDefinitionProperty(node)) {
        let arr: IDefinitionProperty[] | any[] = this.swaggerService.getRef(SwaggerTools.getDefinitionPropertyType(node));
        for (let p of arr) {
          stack.push({ ...p, level: node.level + 1, expand: false, parent: node });
        }
      }
    }
    return array;
  }

  private visitNode(node, hashMap, array) {
    if (!hashMap[node.key]) {
      hashMap[node.key] = true;
      array.push(node);
    }
  }
}
